package br.uff.pgci.sgca.gateway.client;

import br.uff.pgci.sgca.gateway.model.Mensagem;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
import org.jboss.netty.channel.socket.DatagramChannel;
import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import org.jboss.netty.util.CharsetUtil;

/**
 *
 */
public class ClienteUDP {

    private static final Logger logger = Logger.getLogger(ClienteUDP.class.getName());

    public void enviaMensagem(Mensagem mensagem) throws Exception {
        DatagramChannelFactory f =
                new NioDatagramChannelFactory(Executors.newCachedThreadPool());

        ConnectionlessBootstrap b = new ConnectionlessBootstrap(f);

        // Configure the pipeline factory.
        b.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                pipeline.addLast("decoder", new StringDecoder(CharsetUtil.ISO_8859_1));
                pipeline.addLast("handler", new ProcessadosDeMensagemDeRetornoHandler());
                pipeline.addLast("encoder", new StringEncoder(CharsetUtil.ISO_8859_1));
                return pipeline;
            }
        });

        // Enable broadcast
        b.setOption("broadcast", "false");

        b.setOption("receiveBufferSizePredictorFactory", new FixedReceiveBufferSizePredictorFactory(1024));

        DatagramChannel c = (DatagramChannel) b.bind(new InetSocketAddress(0));

        String msg = mensagem.processaMensagemParaEnvio();
        
        c.write(msg, new InetSocketAddress(mensagem.getIPEquipamento(), mensagem.getPortaEquipamento()));

        if (!c.getCloseFuture().awaitUninterruptibly(10000)) {
//            logger.log(Level.SEVERE, "Mensagem nao enviada! Fechando canal com Equipamento: {0},{1}",
//                    new Object[]{mensagem.getIPEquipamento(), mensagem.getPortaEquipamento()});
            c.close().awaitUninterruptibly();
        }

        f.releaseExternalResources();
    }

}
